// ============================================================================
// 监控服务 - 监控定时任务、工作流和系统状态
// ============================================================================

import { logger } from '@roasmax/logger'
import { EventEmitter } from 'events'
import { TaskScheduler } from '../core/scheduler'
import { WeiboWorkflowService } from './weibo-workflow-service'
import { RabbitMQManager } from '../core/rabbitmq-manager'
import { useEntityManager, healthCheck } from '../storage/data-source'
import { Task, WeiboData } from '../storage/entities'

/**
 * 系统监控指标
 */
export interface SystemMetrics {
  timestamp: Date
  scheduler: {
    isRunning: boolean
    activeJobs: number
    totalJobs: number
    nextExecution?: Date
  }
  workflow: {
    isRunning: boolean
    currentStats?: any
  }
  rabbitmq: {
    isConnected: boolean
    queuesStatus: Record<string, boolean>
  }
  database: {
    isConnected: boolean
    totalTasks: number
    totalWeiboData: number
  }
  system: {
    memoryUsage: NodeJS.MemoryUsage
    uptime: number
    cpuUsage?: number
  }
}

/**
 * 监控配置
 */
export interface MonitoringConfig {
  enabled: boolean
  interval: number // 监控间隔（毫秒）
  alertThresholds: {
    memoryUsage: number // MB
    errorRate: number // 百分比
    queueBacklog: number // 消息数量
  }
  retentionDays: number
}

/**
 * 监控服务类
 */
export class MonitoringService extends EventEmitter {
  private static instance: MonitoringService
  private config: MonitoringConfig
  private isRunning = false
  private monitoringTimer?: NodeJS.Timeout
  private metrics: SystemMetrics[] = []
  private alerts: Array<{
    id: string
    type: string
    message: string
    timestamp: Date
    resolved: boolean
  }> = []

  constructor(
    private scheduler: TaskScheduler,
    private workflowService: WeiboWorkflowService,
    private rabbitmqManager: RabbitMQManager,
    config?: Partial<MonitoringConfig>
  ) {
    super()
    
    this.config = {
      enabled: true,
      interval: 60 * 1000, // 1分钟
      alertThresholds: {
        memoryUsage: 512, // 512MB
        errorRate: 10, // 10%
        queueBacklog: 1000 // 1000条消息
      },
      retentionDays: 7,
      ...config
    }
  }

  /**
   * 获取单例实例
   */
  static getInstance(
    scheduler?: TaskScheduler,
    workflowService?: WeiboWorkflowService,
    rabbitmqManager?: RabbitMQManager,
    config?: Partial<MonitoringConfig>
  ): MonitoringService {
    if (!MonitoringService.instance && scheduler && workflowService && rabbitmqManager) {
      MonitoringService.instance = new MonitoringService(
        scheduler, workflowService, rabbitmqManager, config
      )
    }
    return MonitoringService.instance
  }

  /**
   * 启动监控服务
   */
  async start(): Promise<void> {
    if (this.isRunning) {
      logger.warn('监控服务已在运行中')
      return
    }

    if (!this.config.enabled) {
      logger.info('监控服务已禁用')
      return
    }

    try {
      this.isRunning = true
      
      // 立即收集一次指标
      await this.collectMetrics()
      
      // 启动定时监控
      this.monitoringTimer = setInterval(async () => {
        try {
          await this.collectMetrics()
          await this.checkAlerts()
          await this.cleanupOldData()
        } catch (error) {
          logger.error('监控数据收集失败', error)
        }
      }, this.config.interval)

      logger.info('监控服务启动成功', {
        interval: this.config.interval,
        alertThresholds: this.config.alertThresholds
      })

      this.emit('monitoring:started')
    } catch (error) {
      this.isRunning = false
      logger.error('启动监控服务失败', error)
      throw error
    }
  }

  /**
   * 停止监控服务
   */
  async stop(): Promise<void> {
    if (!this.isRunning) {
      logger.warn('监控服务未在运行')
      return
    }

    try {
      this.isRunning = false

      if (this.monitoringTimer) {
        clearInterval(this.monitoringTimer)
        this.monitoringTimer = undefined
      }

      logger.info('监控服务已停止')
      this.emit('monitoring:stopped')
    } catch (error) {
      logger.error('停止监控服务失败', error)
      throw error
    }
  }

  /**
   * 收集系统指标
   */
  private async collectMetrics(): Promise<void> {
    try {
      const timestamp = new Date()

      // 收集调度器指标
      const schedulerStatus = this.scheduler.getStatus()

      // 收集工作流指标
      const workflowStats = this.workflowService.getCurrentStats()

      // 收集RabbitMQ指标
      const rabbitmqConnected = this.rabbitmqManager.isConnected()

      // 收集数据库指标
      const [dbStats, allTasks, isDbConnected] = await Promise.all([
        useEntityManager(async m => {
          const weiboRepo = m.getRepository(WeiboData)
          const totalCount = await weiboRepo.count()
          return { totalCount }
        }),
        useEntityManager(async m => {
          const taskRepo = m.getRepository(Task)
          return await taskRepo.find()
        }),
        healthCheck()
      ])

      // 收集系统指标
      const memoryUsage = process.memoryUsage()
      const uptime = process.uptime()

      const metrics: SystemMetrics = {
        timestamp,
        scheduler: {
          isRunning: schedulerStatus.isRunning,
          activeJobs: schedulerStatus.activeJobs,
          totalJobs: schedulerStatus.totalJobs,
          nextExecution: schedulerStatus.nextExecution
        },
        workflow: {
          isRunning: this.workflowService.isWorkflowRunning(),
          currentStats: workflowStats
        },
        rabbitmq: {
          isConnected: rabbitmqConnected,
          queuesStatus: {
            loginSuccess: rabbitmqConnected,
            weiboData: rabbitmqConnected,
            weiboDetail: rabbitmqConnected,
            scheduledTask: rabbitmqConnected
          }
        },
        database: {
          isConnected: isDbConnected,
          totalTasks: allTasks.length,
          totalWeiboData: dbStats.totalCount
        },
        system: {
          memoryUsage,
          uptime
        }
      }

      this.metrics.push(metrics)

      // 限制指标数量
      if (this.metrics.length > 1000) {
        this.metrics = this.metrics.slice(-500)
      }

      logger.debug('系统指标收集完成', {
        schedulerJobs: metrics.scheduler.totalJobs,
        workflowRunning: metrics.workflow.isRunning,
        memoryUsageMB: Math.round(metrics.system.memoryUsage.heapUsed / 1024 / 1024),
        totalTasks: metrics.database.totalTasks
      })

      this.emit('metrics:collected', metrics)
    } catch (error) {
      logger.error('收集系统指标失败', error)
    }
  }

  /**
   * 检查告警
   */
  private async checkAlerts(): Promise<void> {
    if (this.metrics.length === 0) return

    const latestMetrics = this.metrics[this.metrics.length - 1]!

    // 检查内存使用率
    const memoryUsageMB = latestMetrics.system.memoryUsage.heapUsed / 1024 / 1024
    if (memoryUsageMB > this.config.alertThresholds.memoryUsage) {
      this.createAlert('memory_high', `内存使用率过高: ${Math.round(memoryUsageMB)}MB`)
    }

    // 检查调度器状态
    if (!latestMetrics.scheduler.isRunning) {
      this.createAlert('scheduler_stopped', '任务调度器已停止运行')
    }

    // 检查RabbitMQ连接
    if (!latestMetrics.rabbitmq.isConnected) {
      this.createAlert('rabbitmq_disconnected', 'RabbitMQ连接已断开')
    }
  }

  /**
   * 创建告警
   */
  private createAlert(type: string, message: string): void {
    // 检查是否已存在相同类型的未解决告警
    const existingAlert = this.alerts.find(alert => 
      alert.type === type && !alert.resolved
    )

    if (existingAlert) {
      return // 避免重复告警
    }

    const alert = {
      id: `${type}_${Date.now()}`,
      type,
      message,
      timestamp: new Date(),
      resolved: false
    }

    this.alerts.push(alert)

    logger.warn('系统告警', alert)
    this.emit('alert:created', alert)
  }

  /**
   * 解决告警
   */
  resolveAlert(alertId: string): void {
    const alert = this.alerts.find(a => a.id === alertId)
    if (alert) {
      alert.resolved = true
      logger.info('告警已解决', { alertId, type: alert.type })
      this.emit('alert:resolved', alert)
    }
  }

  /**
   * 获取最新指标
   */
  getLatestMetrics(): SystemMetrics | null {
    return this.metrics.length > 0 ? this.metrics[this.metrics.length - 1]! : null
  }

  /**
   * 获取历史指标
   */
  getHistoricalMetrics(hours: number = 24): SystemMetrics[] {
    const cutoffTime = new Date(Date.now() - hours * 60 * 60 * 1000)
    return this.metrics.filter(metric => metric.timestamp >= cutoffTime)
  }

  /**
   * 获取活跃告警
   */
  getActiveAlerts(): Array<any> {
    return this.alerts.filter(alert => !alert.resolved)
  }

  /**
   * 获取监控统计
   */
  getMonitoringStats(): {
    isRunning: boolean
    metricsCount: number
    activeAlerts: number
    uptime: number
  } {
    return {
      isRunning: this.isRunning,
      metricsCount: this.metrics.length,
      activeAlerts: this.getActiveAlerts().length,
      uptime: this.isRunning ? Date.now() - (this.metrics[0]?.timestamp.getTime() || Date.now()) : 0
    }
  }

  /**
   * 更新监控配置
   */
  updateConfig(config: Partial<MonitoringConfig>): void {
    this.config = { ...this.config, ...config }
    logger.info('监控配置已更新', this.config)
    this.emit('config:updated', this.config)
  }

  /**
   * 清理旧数据
   */
  private async cleanupOldData(): Promise<void> {
    const cutoffTime = new Date(Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1000)
    
    // 清理旧指标
    const oldMetricsCount = this.metrics.length
    this.metrics = this.metrics.filter(metric => metric.timestamp >= cutoffTime)
    
    // 清理旧告警
    const oldAlertsCount = this.alerts.length
    this.alerts = this.alerts.filter(alert => 
      alert.timestamp >= cutoffTime || !alert.resolved
    )

    if (oldMetricsCount !== this.metrics.length || oldAlertsCount !== this.alerts.length) {
      logger.debug('清理旧监控数据', {
        removedMetrics: oldMetricsCount - this.metrics.length,
        removedAlerts: oldAlertsCount - this.alerts.length
      })
    }
  }
}
